package com.cie2.janji.pages.users;

import java.io.File;
import java.util.Date;
import java.util.List;

import org.apache.commons.fileupload.FileUploadException;
import org.apache.log4j.Logger;
import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.hibernate.annotations.CommitAfter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.services.PropertyAccess;
import org.apache.tapestry5.services.ApplicationGlobals;
import org.apache.tapestry5.upload.services.UploadedFile;
import org.chenillekit.tapestry.core.components.Editor;
import org.joda.time.DateTime;

import com.cie2.janji.base.CieUserPage;
import com.cie2.janji.entities.BaseEntity;
import com.cie2.janji.entities.Category;
import com.cie2.janji.entities.Promise;
import com.cie2.janji.entities.User;
import com.cie2.janji.models.EasyIdSelectModel;
import com.cie2.janji.services.BaseEntityService;
import com.cie2.janji.services.CategoryService;
import com.cie2.janji.services.PromiseService;
import com.cie2.janji.services.PromiseStatisticsService;

public class CreatePromise extends CieUserPage{
	static Logger logger =
	       Logger.getLogger(CreatePromise.class.getName());

	private Long promiseId;

	@Property
	private Promise promise;
	
	@SuppressWarnings("unused")
	@Property
	@Persist
	private EasyIdSelectModel<BaseEntity> myModel;	

	@Inject
	private PropertyAccess propertyAccess;
	
	@Property
	private Long entityId;

	@SuppressWarnings("unused")
	@Property
	@Persist
	private EasyIdSelectModel<Category> categoryModel;	

	@Property
	private Long categoryId;

	@Component(parameters = {"value=editor1Value"})
	private Editor editor1;

	@Component(parameters = {"value=editor2Value"})
	private Editor editor2;
	
	@Property
	private String editor1Value;

	@Property
	private String editor2Value;

	// for uploaded file
	@Property
	private UploadedFile file;

	@Property
	private Date startDate;
	
	@Property
	private Date endDate;

	@Inject 
	private ApplicationGlobals applicationGlobals;
	
	//service
	@Inject 
	private PromiseService promiseService;
	
	@Inject 
	private PromiseStatisticsService statisticsService;
	
	@Inject
	private BaseEntityService baseEntityService;
	
	@Inject
	private CategoryService categoryService;
	
	@CommitAfter
	Object onSuccess() {

		if(null == promiseId) {
			logger.debug("=== Add Promise");
			addPromise();
		}
		else {
			logger.debug("=== Update promise " + promiseId);
			updatePromise();			
		}
		
		
		return PromiseList.class;
	}

	
	private void addPromise() {
		BaseEntity entity = baseEntityService.load(entityId);
		Category category = categoryService.load(categoryId);

		if(file != null) {
			
			String realPath = applicationGlobals.getServletContext().getRealPath("/");
			
			String filename = "P_" + file.getFileName();
			File copied = new File(realPath + File.separatorChar +"images" + File.separatorChar  
					 + File.separatorChar + filename);
	
			file.write(copied);

			promise.setImage(filename);
			
		} else  {
			promise.setImage(entity.getImage());
		}  		
		
		User currentUser = getVisit().getUser();		
		promise.setAuthor(currentUser);
		promise.setEntity(entity);
		promise.setCategory(category);
		promise.setAbstraction(editor1Value);
		promise.setQuote(editor2Value);
		
		promise.setCreatedDate(new Date());
		promise.setStartDate(startDate);
		promise.setEndDate(endDate);
		promise.setPercentage(0);
		
		
		promiseService.add(promise);
		
		statisticsService.addPromise(promise);

//		statisticsService.getPC(promise);
		

	}

	private void updatePromise() {
		BaseEntity entity = baseEntityService.load(entityId);
		Category category = categoryService.load(categoryId);
		
		// rollback statistics
		if(entityId != promise.getEntity().getId() ){
			statisticsService.updatePromiseEntityStatistic(promise, entityId);			
		}
		
		if(categoryId != promise.getCategory().getId()) {
			statisticsService.updatePromiseCategoryStatistic(promise, categoryId);
		}
		
		promise.setEntity(entity);
		promise.setCategory(category);
		promise.setAbstraction(editor1Value);
		promise.setQuote(editor2Value);
		
		promise.setUpdatedDate(new Date());
		promise.setStartDate(startDate);
		promise.setEndDate(endDate);
		
		promiseService.add(promise);
	}
	
	
	// error handling for upload file
	@Persist(PersistenceConstants.FLASH)
	@Property
	private String message;

	Object onUploadException(FileUploadException ex) {
		message = "Upload exception: " + ex.getMessage();

		return this;
	}

    void beginRender() {
    	if(null == myModel) {
    		logger.debug("Creating model for entity");

    		List<BaseEntity> entities = baseEntityService.getAll();
    		logger.debug("Refresh entity size : " + entities.size());
    		myModel = new EasyIdSelectModel<BaseEntity>(entities, BaseEntity.class, "name", "id", propertyAccess);    	
    	} else {
			List<BaseEntity> entities = baseEntityService.getAll();
			logger.debug("Refresh category size : " + entities.size());
			myModel.setList(entities);
		}
    		
    	if(null == categoryModel) {
    		logger.debug("Creating model for category ");

    		List<Category> categories = categoryService.getAll();
    		logger.debug("Refresh category size : " + categories.size());
    		categoryModel = new EasyIdSelectModel<Category>(categories, Category.class, "name", "id", propertyAccess);    	
    	} else {
			List<BaseEntity> categories = categoryService.getAll();
			logger.debug("Refresh category size : " + categories.size());
			categoryModel.setList(categories);
		}
    	
    	if(null == startDate)
    		startDate = new Date();
    	
    	if (null == endDate) {
			DateTime dt = new DateTime();
			dt = dt.plusYears(1);
			endDate = dt.toDate();
		}
    }
    
	Long onPassivate() {
		return promiseId;
	}

	void onActivate(Long promiseId) {
		this.promiseId = promiseId;
		promise = promiseService.load(promiseId);
		entityId = promise.getEntity().getId();
		categoryId = promise.getCategory().getId();
		editor1Value = promise.getAbstraction();
		editor2Value = promise.getQuote();
		startDate = promise.getStartDate();
		endDate = promise.getEndDate();
	}
}
